<style lang="scss">
.z-style-editor {
  .el-form-item {
    margin-bottom: 10px;
  }
  .el-form-item__content {
    line-height: 1;
  }
}
.z-style-popover  + .CodeMirror {
  .CodeMirror-sizer {
    margin-left: 29px !important;
  }
  .CodeMirror-linenumber {
    //left: -29px !important;
  }
}
</style>

<template>
  <div class="z-style-editor" v-if="inited">
<!--    {{value}}-->
   <z-easy-popover title="源码" :button-attr="{size: 'small'}"
                   @popover-show="onPopoverShow"
                   :model-attr="{width: '350px', placement: 'left', appendToBoby: true}">
      <div style="position: relative; width: 320px">
        <CodeMirror
            class="z-style-popover"
            ref="editorRef"
            v-model="content"
            :height="styleObj.height"
            :mode="mode"
            theme="monokai"
        />
      </div>
   </z-easy-popover>
    <div style="height: 0; overflow: hidden">
      <CodeMirror
          class="z-style-popover"
          ref="hideEditorRef"
          v-model="content"
          @update:modelValue="editorChange"
          :height="styleObj.height"
          :mode="mode"
          theme="monokai"
      />
    </div>
    <div style="height: 10px"> </div>
    <el-form v-model="styleModel">
      <el-form-item label="类型" >
        <el-select v-model="currentType"
                   @change="onTypeChange">
          <el-option
              v-for="(option, index) in keys"
              :label="option.label"
              :value="option.value"
          />
        </el-select>
      </el-form-item>
      <el-row :gutter="10">
        <el-col :span="12">
         <el-form-item label="背景色" >
           <el-color-picker v-model="styleModel.backgroundColor"
                            @change="onChange(['backgroundColor'],$event)"
                            clearable
                            show-alpha
           ></el-color-picker>
         </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="颜色" >
            <el-color-picker v-model="styleModel.color"
                             @change="onChange(['color'],$event)"
                             clearable
                             show-alpha
            ></el-color-picker>
          </el-form-item>
        </el-col>
      </el-row>
      <el-form-item label="宽度" >
        <unit-input v-model="styleModel.width"
                    default-unit="px"
                    @change="onChange(['width'],$event)"></unit-input>
      </el-form-item>
      <el-form-item label="高度" >
        <unit-input v-model="styleModel.height"
                    default-unit="px"
                    @change="onChange(['height'],$event)"></unit-input>
      </el-form-item>
      <el-form-item label="显示" >
        <el-radio-group v-model="styleModel.display"
                        @change="onChange(['display'],$event)"
        >
          <el-radio-button label="block">block</el-radio-button>
          <el-radio-button label="inline">inline</el-radio-button>
          <el-radio-button label="inline-block">inline-block</el-radio-button>
          <el-radio-button label="flex">flex</el-radio-button>
        </el-radio-group>
      </el-form-item>
      <div class="a-space-mb-10">
        <el-collapse v-model="activeNames" >
          <el-collapse-item title="Margin" name="1">
            <template #title><div style="font-weight: bold">Margin</div></template>
            <el-form-item label="marginLeft" >
              <unit-input v-model="styleModel.marginLeft"
                          default-unit="px"
                          @change="onChange(['marginLeft'],$event)"></unit-input>
            </el-form-item>
            <el-form-item label="marginTop" >
              <unit-input v-model="styleModel.marginTop"
                          default-unit="px"
                          @change="onChange(['marginTop'],$event)"></unit-input>
            </el-form-item>
            <el-form-item label="marginBottom" >
              <unit-input v-model="styleModel.marginBottom"
                          default-unit="px"
                          @change="onChange(['marginBottom'],$event)"></unit-input>
            </el-form-item>
            <el-form-item label="marginRight" >
              <unit-input v-model="styleModel.marginRight"
                          default-unit="px"
                          @change="onChange(['marginRight'],$event)"></unit-input>
            </el-form-item>
          </el-collapse-item>
          <el-collapse-item title="Padding" name="2">
            <template #title><div style="font-weight: bold">Padding</div></template>
            <el-form-item label="paddingLeft" >
              <unit-input v-model="styleModel.paddingLeft"
                          default-unit="px"
                          @change="onChange(['paddingLeft'],$event)"></unit-input>
            </el-form-item>
            <el-form-item label="paddingTop" >
              <unit-input v-model="styleModel.paddingTop"
                          default-unit="px"
                          @change="onChange(['paddingTop'],$event)"></unit-input>
            </el-form-item>
            <el-form-item label="paddingBottom" >
              <unit-input v-model="styleModel.paddingBottom"
                          default-unit="px"
                          @change="onChange(['paddingBottom'],$event)"></unit-input>
            </el-form-item>
            <el-form-item label="paddingRight" >
              <unit-input v-model="styleModel.paddingRight"
                          default-unit="px"
                          @change="onChange(['paddingRight'],$event)"></unit-input>
            </el-form-item>
          </el-collapse-item>
          <el-collapse-item title="Position" name="3">
            <template #title><div style="font-weight: bold">Position</div></template>
            <el-form-item label="left" >
              <unit-input v-model="styleModel.left"
                          default-unit="px"
                          @change="onChange(['left'],$event)"></unit-input>
            </el-form-item>
            <el-form-item label="top" >
              <unit-input v-model="styleModel.top"
                          default-unit="px"
                          @change="onChange(['top'],$event)"></unit-input>
            </el-form-item>
            <el-form-item label="right" >
              <unit-input v-model="styleModel.right"
                          default-unit="px"
                          @change="onChange(['right'],$event)"></unit-input>
            </el-form-item>
            <el-form-item label="bottom" >
              <unit-input v-model="styleModel.bottom"
                          default-unit="px"
                          @change="onChange(['bottom'],$event)"></unit-input>
            </el-form-item>
          </el-collapse-item>
        </el-collapse>
      </div>
      <el-form-item label="overflow" >
        <el-input v-model="styleModel.overflow"
                  @change="onChange(['overflow'],$event)"
                  clearable
        ></el-input>
      </el-form-item>
      <el-form-item label="其他" >
        <template #label>其他
          <el-tooltip placement="top">
            <template #content> 参考 <br> prop1: value;<br />prop2: value;<br /> </template>
            <i class="fa fa-question-circle"></i>
          </el-tooltip>
        </template>
        <el-input type="textarea" v-model="styleModel.other"
                  @change="onChange(['other'],$event)"
                  :rows="10"
                  clearable
        ></el-input>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
import UnitInput from "@/components/UnitInput.vue";
import {toRaw} from "vue";
import ZEasyPopover from "@/plugins/z-frame/ZEasyPopover.vue";
export default {
  name: 'ZStyleEditor',
  components: {ZEasyPopover, UnitInput},
  props: {
    value: String,
    extKeys: {
      type: Array,
      default() {
        return []
      }
    }
  },
  data() {
    let keys =  [
      {
        label: '默认状态',
        value: ':host',
      },
      {
        label: ':hover',
        value: ':host(:hover) ',
      },
      {
        label: ':focus',
        value: ':host(:focus) ',
      },
      {
        label: ':active',
        value: ':host(:active) ',
      },
    ].concat(this.extKeys)
    return {
      lock: new ZY.Lock(),
      mode: 'text/css',
      content: '',
      showMirror: false,
      styleObj: {
      },
      styleModel: {
      },
      cached: {},
      currentType: keys[0].value,
      keys: keys,
      activeNames: [],
      inited: false
    }
  },
  watch: {
    value(newVal) {
      this.init(newVal)
    }
  },
  methods: {
    editorChange: function (e) {
      // console.log('editorChange', e)
      this.lock.lock( () => {
        // this.$emit('update:modelValue', e)
        this.$emit('val:change',
            ZY.JSON5.stringify({
              cached: toRaw(this.cached),
              css: e
            })
        );
      }, 1000)
    },
    changeModel(type = this.currentType) {
      this.styleModel = this.cached[type]
    },
    setContent(v) {
      this.content = v
    },
    onChange(pathArr = [], e) {
      let path =
          ZY.getObjPathFromPathArr(pathArr)
      // console.log(path, e)
      ZY.lodash.set(this.styleModel, path, e)
      this.$nextTick(() => {
        this.setContent(this.buildStyleContent())
        setTimeout(() => {
          if (this.$refs.hideEditorRef && this.$refs.hideEditorRef.setModel) {
            this.$refs.hideEditorRef.setModel(this.content)
          }
        }, 30)
      })
    },
    buildStyleItem(style, key) {
      // console.log(style, key)
      let keys = Object.keys(style)
      // let value = JSON.stringify(style, null ,2).replaceAll(/"/g, '')
      let props = Object.entries(style).map(([k, v]) => {
        if (!v) {
          return '';
        }
        let propKey = ZY.camel2hyphen(k);
        if (propKey === 'other') {
          console.log('sdsdsdsdsdsd', propKey, v)
          return v;
        } else {
          return ` ${propKey}: ${v};`
        }
      })
      let value = props.filter(v => v).join('\n');
      if (keys.length > 0) {
        return `${key} {
${value}
}`
      }
      return ''
    },
    buildStyleContent() {
      let content = ''
      ZY.lodash.each(this.cached, (style, key) => {
        let c = this.buildStyleItem(style, key)
        if (key !== this.keys[0].value && c) {
          content = content + '\n'
        }
        content = content + c
      })
      // console.log(content)
      return content
    },
    onTypeChange(v) {
      // console.log(this.styleModel, v)
      this.changeModel(v)
    },
    /**
     *
     */
    onPopoverShow() {
      this.showMirror = true
      setTimeout(() => {
        // console.log('onPopoverShow', this.$refs.editorRef)
        if (this.$refs.editorRef && this.$refs.editorRef.setModel) {
          this.$refs.editorRef.setModel(this.content)
        }
      }, 30)
    },
    init(newVal = this.value) {
      let cached = {}
      if (newVal) {
        try {
          let obj = ZY.JSON5.parse(newVal);
          cached = obj?.cached ?? {}
          // console.log(cached)
          if (obj.css) {
            this.lock.lock( () => {
              this.setContent(obj.css)
            }, 1000)
          }
        } catch (e) {}
      }
      this.keys.forEach(key => {
        this.cached[key.value] = cached[key.value] ?? {}
      })
      // console.log(this.value)
      this.changeModel()
    }
  },
  mounted() {
    globalThis.initCodeMirror().then(() => {
      this.inited = true
      this.init()
    })
  }
}
</script>
